home *** CD-ROM | disk | FTP | other *** search
-
- /*--------------------------
- Inclusions
- --------------------------*/
-
- #include <QuickDraw.h>
- #include <Windows.h>
- #include <StandardFile.h>
- #include <OSUtils.h>
- #include <Script.h>
- #include <QuickTimeComponents.h>
-
- #include "BigEasy2.h"
-
- /*--------------------------
- Limits and Konstants
- --------------------------*/
- enum
- {
- mOpen = 100,
- mClose
- };
-
- typedef struct
- {
- WindowPtr w;
- } Globals;
-
- static Globals g;
-
-
- /*--------------------------
- Prototypes
- --------------------------*/
- static void GoAwayDoc(short n);
- static void LetsQuit(short n,short menuItem,short menuRef);
- static void OpenWindow(short n,short menuItem,short menuRef);
- static void InitVars(void);
-
- static void SDrawDoc(short n);
- static void SClickDoc(short n,Point p,short mods);
- static void SKeyDoc(short n,short key,short code,short mods);
- static void SIdleDoc(short n, Boolean front);
-
- void ActivateDoc(short n);
- void DeactivateDoc(short n);
-
-
- /*--------------------------
- Computer Programs
- --------------------------*/
-
-
-
-
- void PlaySomeNotes(short a,short b,short c);
- void PickThenPlaySomeNotes(short xx1,short xx2,short xx3);
- void PlaySomeBentNotes(short xx1,short xx2,short xx3);
- unsigned long *BuildTuneHeader(long *longCount);
- Handle BuildTuneSequence(long *duration);
- void BuildSequenceAndPlay(short xx1,short xx2,short xx3);
- void BuildMusicMovie(short xx1,short xx2,short xx3);
- void UseMIDIInput(short xx1,short xx2,short xx3);
-
-
- void PlaySomeNotes(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- NoteAllocator na;
- NoteChannel nc;
- NoteRequest nr;
- ComponentResult thisError;
- long t,i;
-
- na = 0;
- nc = 0;
-
- /*
- * Open up the Note Allocator
- */
- na = OpenDefaultComponent('nota',0);
- if(!na)
- goto goHome;
-
- /*
- * Fill out a Note Request using NAStuffToneDescription
- * to help, and allocate a Note Channel
- */
- nr.polyphony = 2; /* simultaneous tones */
- nr.typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,1,&nr.tone); /* 1 is Piano */
-
- thisError = NANewNoteChannel(na,&nr,&nc);
- if(thisError || !nc)
- goto goHome;
-
- /*
- * If we've gotten this far, then things are ok
- * to play some musical notes. Lovely.
- */
- NAPlayNote(na,nc,60,80); /* middle C at velocity 80 */
- Delay(40,&t); /* delay 2/3 of a second */
- NAPlayNote(na,nc,60,0); /* middle C at velocity 0: end note */
- Delay(40,&t); /* delay 2/3 of a second */
-
- /*
- * Obligatory do-loop of rising tones
- */
- for(i = 60; i <= 84; i++)
- {
- NAPlayNote(na,nc,i,80); /* pitch i at velocity 80 */
- NAPlayNote(na,nc,i+7,80); /* pitch i+7 (musical fifth) at velocity 80 */
- Delay(10,&t); /* delay 1/6 of a second */
- NAPlayNote(na,nc,i,0); /* pitch i at velocity 0: end note */
- NAPlayNote(na,nc,i+7,0); /* pitch i+7 at velocity 0: end note */
- }
- goHome:
- if(nc)
- NADisposeNoteChannel(na,nc);
- if(na)
- CloseComponent(na);
- }
-
- void PlayShepardMelody(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */;
- void PlayShepardMelody(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- NoteAllocator na;
- NoteChannel nc;
- NoteRequest nr;
- ComponentResult thisError;
- unsigned long i,j,v;
- long t;
-
- na = 0;
- nc = 0;
-
- /*
- * Open up the Note Allocator
- */
- na = OpenDefaultComponent('nota',0);
- if(!na)
- goto goHome;
-
- /*
- * Fill out a Note Request using NAStuffToneDescription
- * to help, and allocate a Note Channel
- */
- nr.polyphony = 3; /* simultaneous tones */
- nr.typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,1,&nr.tone); /* 1 is Piano */
-
- thisError = NANewNoteChannel(na,&nr,&nc);
- if(thisError || !nc)
- goto goHome;
-
- /*
- * play Roger Shepard's melody
- */
- i = 0;
- while(!Button())
- {
- for(j = i % 13; j < 128; j+=13)
- {
- v = j<64 ? j * 2 : (127 - j) * 2;
- NAPlayNote(na,nc,j,v);
- }
- Delay(13,&t);
- for(j = i % 13; j < 128; j+=13)
- NAPlayNote(na,nc,j,0);
- i++;
- }
- goHome:
- if(nc)
- NADisposeNoteChannel(na,nc);
- if(na)
- CloseComponent(na);
- }
-
-
-
- void PickThenPlaySomeNotes(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- NoteAllocator na;
- NoteChannel nc;
- NoteRequest nr;
- ComponentResult thisError;
- long t,i;
-
- na = 0;
- nc = 0;
-
- /*
- * Open up the Note Allocator
- */
- na = OpenDefaultComponent('nota',0);
- if(!na)
- goto goHome;
-
- /*
- * Fill out a Note Request using NAStuffToneDescription
- * to help, and allocate a Note Channel
- */
- nr.polyphony = 2; /* simultaneous tones */
- nr.typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,1,&nr.tone); /* 1 is Piano */
-
- thisError = NAPickInstrument(na,nil,"\pPick An Instrument:",&nr.tone, 0,0,0,0);
- if(thisError)
- goto goHome;
-
- thisError = NANewNoteChannel(na,&nr,&nc);
- if(thisError || !nc)
- goto goHome;
-
- /*
- * If we've gotten this far, then things are ok
- * to play some musical notes. Lovely.
- */
- NAPlayNote(na,nc,60,80); /* middle C at velocity 80 */
- Delay(40,&t); /* delay 2/3 of a second */
- NAPlayNote(na,nc,60,0); /* middle C at velocity 0: end note */
- Delay(40,&t); /* delay 2/3 of a second */
-
- /*
- * Obligatory do-loop of rising tones
- */
- for(i = 60; i <= 84; i++)
- {
- NAPlayNote(na,nc,i,80); /* pitch i at velocity 80 */
- NAPlayNote(na,nc,i+7,80); /* pitch i+7 (musical fifth) at velocity 80 */
- Delay(10,&t); /* delay 1/6 of a second */
- NAPlayNote(na,nc,i,0); /* pitch i at velocity 0: end note */
- NAPlayNote(na,nc,i+7,0); /* pitch i+7 at velocity 0: end note */
- }
- goHome:
- if(nc)
- NADisposeNoteChannel(na,nc);
- if(na)
- CloseComponent(na);
- }
-
-
-
- void PlaySomeBentNotes(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- NoteAllocator na;
- NoteChannel nc;
- NoteRequest nr;
- ComponentResult thisError;
- long t,i;
-
- na = 0;
- nc = 0;
-
- /*
- * Open up the Note Allocator
- */
- na = OpenDefaultComponent('nota',0);
- if(!na)
- goto goHome;
-
- /*
- * Fill out a Note Request using NAStuffToneDescription
- * to help, and allocate a Note Channel
- */
- nr.polyphony = 2; /* simultaneous tones */
- nr.typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,17,&nr.tone); /* 17 is an organ tone */
-
- thisError = NANewNoteChannel(na,&nr,&nc);
- if(thisError || !nc)
- goto goHome;
-
- Delay(30,&t);
-
- /*
- * If we've gotten this far, then things are ok
- * to play some musical notes. Lovely.
- */
- NAPlayNote(na,nc,60,80); /* middle C at velocity 80 */
- NAPlayNote(na,nc,67,60); /* g at velocity 60 */
- Delay(30,&t);
-
- /*
- * Loop through differing pitch bendings
- */
- for(i = 0; i <= 768; i+= 10) /* bend 3 semitones */
- {
- NASetController(na,nc,kControllerPitchBend,i);
- Delay(1,&t);
- }
- Delay(30,&t);
- for(i = 768; i >= 0; i-= 10) /* bend back to normal*/
- {
- NASetController(na,nc,kControllerPitchBend,i);
- Delay(1,&t);
- }
- Delay(30,&t);
-
- NAPlayNote(na,nc,60,0); /* middle C off */
- NAPlayNote(na,nc,67,0); /* G off */
-
- goHome:
- if(nc)
- NADisposeNoteChannel(na,nc);
- if(na)
- CloseComponent(na);
- }
-
-
- #define kNoteRequestHeaderEventLength (sizeof(NoteRequest)/sizeof(long) + 2) /* longwords */
- unsigned long *BuildTuneHeader(long *longCount)
- {
- unsigned long *header;
- unsigned long *w,*w2;
- NoteRequest *nr;
- NoteAllocator na; /* just for the NAStuffToneDescription call */
- ComponentResult thisError;
-
- header = 0;
- na = 0;
-
- /*
- * Open up the Note Allocator
- */
- na = OpenDefaultComponent('nota',0);
- if(!na)
- goto goHome;
-
- /*
- * Allocate space for the tune header,
- * rather inflexibly.
- */
- header = (unsigned long *)
- NewPtrClear((2 * kNoteRequestHeaderEventLength + 1) * sizeof(long));
- if(!header)
- goto goHome;
-
- w = header;
-
- /*
- * Stuff request for piano polyphony 4
- */
- w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
- _StuffGeneralEvent(*w,*w2, 1, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
- nr = (NoteRequest *)(w + 1);
- nr->polyphony = 4; /* simultaneous tones */
- nr->typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,1,&nr->tone); /* 1 is Piano */
- w += kNoteRequestHeaderEventLength;
-
- /*
- * Stuff request for violin polyphony 3
- */
- w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
- _StuffGeneralEvent(*w,*w2, 2, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
- nr = (NoteRequest *)(w + 1);
- nr->polyphony = 3; /* simultaneous tones */
- nr->typicalPolyphony = 0x00010000;
- thisError = NAStuffToneDescription(na,41,&nr->tone); /* ???!!! what is violin? */
- w += kNoteRequestHeaderEventLength;
-
- *w++ = 0x60000000; /* end of sequence marker */
-
-
- goHome:
- if(na)
- CloseComponent(na);
-
- if(longCount)
- *longCount = 2 * kNoteRequestHeaderEventLength;
-
- return header;
- }
-
- Handle BuildTuneSequence(long *duration)
- {
- unsigned long *sequence;
- unsigned long *w;
- Handle h;
-
- /*
- * Allocate space for the tune sequence,
- * rather inflexibly.
- */
- #define kNoteDuration 240 /* in 600ths of a second */
- #define kRestDuration 300 /* in 600ths - tempo will be 120bpm */
-
- h = NewHandleClear(22 * sizeof(long));
- if(!h)
- goto goHome;
- HLock(h);
- sequence = (unsigned long *) *h;
-
- w = sequence;
-
- _StuffNoteEvent(*w++,1,60,100,kNoteDuration); /* piano C */
- _StuffRestEvent(*w++,kRestDuration);
- _StuffNoteEvent(*w++,2,60,100,kNoteDuration); /* violin C */
- _StuffRestEvent(*w++,kRestDuration);
-
- _StuffNoteEvent(*w++,1,63,100,kNoteDuration); /* piano */
- _StuffRestEvent(*w++,kRestDuration);
- _StuffNoteEvent(*w++,2,64,100,kNoteDuration); /* violin */
- _StuffRestEvent(*w++,kRestDuration);
-
- /*
- * make the 5th and 6th notes much softer, just for fun
- */
- _StuffNoteEvent(*w++,1,67,60,kNoteDuration); /* piano */
- _StuffRestEvent(*w++,kRestDuration);
- _StuffNoteEvent(*w++,2,66,60,kNoteDuration); /* violin */
- _StuffRestEvent(*w++,kRestDuration);
-
- _StuffNoteEvent(*w++,1,72,100,kNoteDuration); /* piano */
- _StuffRestEvent(*w++,kRestDuration);
- _StuffNoteEvent(*w++,2,73,100,kNoteDuration); /* violin */
- _StuffRestEvent(*w++,kRestDuration);
-
- _StuffNoteEvent(*w++,1,60,100,kNoteDuration); /* piano */
- _StuffNoteEvent(*w++,1,67,100,kNoteDuration); /* piano */
- _StuffNoteEvent(*w++,2,63,100,kNoteDuration); /* violin */
- _StuffNoteEvent(*w++,2,72,100,kNoteDuration); /* violin */
- _StuffRestEvent(*w++,kRestDuration);
-
- *w++ = 0x60000000; /* end marker */
-
- goHome:
- if(duration)
- *duration = 9 * kRestDuration;
- return h;
- }
-
-
- void BuildSequenceAndPlay(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- Handle sequenceH;
- unsigned long *header;
- unsigned long *sequence;
- TunePlayer tp;
- TuneStatus ts;
- ComponentResult thisError;
-
- tp = 0;
-
- header = BuildTuneHeader(nil);
- sequenceH = BuildTuneSequence(nil);
-
- if(!sequenceH || !header)
- goto goHome;
-
- sequence = (unsigned long *)*sequenceH;
-
- tp = OpenDefaultComponent(kTunePlayerType,0);
- if(!tp)
- goto goHome;
-
- thisError = TuneSetHeader(tp,header);
-
- {
- long t;
- Delay(10,&t);
- }
-
- thisError = TuneQueue(tp,sequence,0x00010000,0,0x7FFFFFFF,0,0,0);
-
- /*
- * wait until the sequence finishes playing,
- * or the user clicks the mouse.
- */
- spin:
- thisError = TuneGetStatus(tp,&ts);
- if(ts.queueTime && !Button())
- goto spin; /* I like to use gotos primarily to shock the children. */
-
- goHome:
- if(tp)
- CloseComponent(tp);
- if(header)
- DisposePtr((Ptr)header);
- if(sequenceH)
- DisposeHandle(sequenceH);
- }
-
-
- typedef struct
- {
- NoteAllocator na;
- NoteChannel nc;
- } MIDIInputExample;
-
- pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon);
- pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon)
- {
- MIDIInputExample *mie;
- Boolean major;
- short status,pitch,vel;
-
- mie = (MIDIInputExample *)refCon;
-
- // if(mp->reserved == kMusicPacketPortLost) /* port gone? make channel quiet */
- // NASetNoteChannelVolume(mie->na,mie->nc,0);
- // else if(mp->reserved == kMusicPacketPortFound) /* port back? raise volume */
- // NASetNoteChannelVolume(mie->na,mie->nc,0x00010000);
- // else
- if(mp->length == 3)
- {
- status = mp->data[0] & 0xF0;
- pitch = mp->data[1];
- vel = mp->data[2];
- switch(status)
- {
- case 0x80:
- vel = 0;
- /* falls into case 0x90. Almost as fun as a goto, hmm, mom? */
- case 0x90:
- major = pitch % 5 == 0;
- NAPlayNote(mie->na,mie->nc,pitch,vel);
- NAPlayNote(mie->na,mie->nc,pitch+3+major,vel);
- NAPlayNote(mie->na,mie->nc,pitch+7,vel);
- break;
- }
- }
- return noErr;
- }
-
-
- void UseMIDIInput(short xx1,short xx2,short xx3)
- {
- ComponentResult result;
- MIDIInputExample mie;
- NoteRequest nr;
- MusicMIDIReadHookUPP readHookUPP = nil;
-
- mie.na = OpenDefaultComponent('nota',0);
- if(!mie.na)
- goto goHome;
-
- nr.polyphony = 2;
- nr.typicalPolyphony = 0x00010000;
- result = NAStuffToneDescription(mie.na,1,&nr.tone); /* piano */
- result = NANewNoteChannel(mie.na,&nr,&mie.nc);
-
- readHookUPP = NewMusicMIDIReadHookProc(AReadHook);
- result = NAUseDefaultMIDIInput(mie.na,readHookUPP,(long)&mie,0);
- while(!Button());
- result = NALoseDefaultMIDIInput(mie.na);
-
- goHome:
- if(readHookUPP)
- DisposeRoutineDescriptor(readHookUPP);
- if(mie.na)
- CloseComponent(mie.na); /* disposes notechannel too */
- }
-
-
-
-
- void BuildMusicMovie(short xx1,short xx2,short xx3) /* dummy arguments for big easy shell */
- {
- ComponentResult result;
- StandardFileReply reply;
- short resRefNum;
- Movie mo;
- Track tr;
- Media me;
- MusicDescription *md,**mdH;
- long duration,headerLength;
- unsigned long *w,*header;
- Handle tuneH;
-
- // • prompt user for new file name
-
- StandardPutFile ("\pMusic movie file name:", "\pMovie File", &reply );
- if(!reply.sfGood)
- goto goHome;
-
- // • create the movie, and track, and media
-
- result = CreateMovieFile(&reply.sfFile,'TVOD',smCurrentScript,createMovieFileDeleteCurFile,&resRefNum,&mo);
- tr = NewMovieTrack(mo,0,0,256);
- me = NewTrackMedia(tr,MusicMediaType, 600, nil, 0 );
-
- // • create a music sample description
-
- header = BuildTuneHeader(&headerLength);
-
- mdH = (MusicDescription **)NewHandleClear(sizeof(MusicDescription) - 4
- + headerLength*sizeof(long)
- + 4); /* end marker */
- if(!mdH)
- goto goHome;
-
- md = *mdH;
- md->descSize = GetHandleSize((Handle)mdH);
- md->dataFormat = 'musi';
- w = md->headerData;
- BlockMove(header,w,headerLength * sizeof(long));
- w += headerLength;
- *w = 0x60000000;
-
- DisposePtr((Ptr)header);
-
- // • Get a tune, and add it to the media, then finish up.
-
- tuneH = BuildTuneSequence(&duration);
-
- result = BeginMediaEdits(me);
-
- result = AddMediaSample(me,tuneH,0,
- GetHandleSize(tuneH),
- duration,(SampleDescriptionHandle)mdH,
- 1,0,nil);
-
- result = EndMediaEdits(me);
- result = InsertMediaIntoTrack(tr,0,0,duration,(1L<<16));
-
- result = OpenMovieFile(&reply.sfFile, &resRefNum,
- fsRdWrPerm);
- result = AddMovieResource( mo,resRefNum, 0, 0);
- result = CloseMovieFile(resRefNum);
-
- DisposeMovie(mo);
- goHome:;
- }
-
-
- void GoAwayDoc(short n)
- /*
- * Close that window...
- */
- {
- UninstallWindow(n);
- }
-
- void ActivateDoc(short n)
- {
- #pragma unused (n)
- SetMenuItem(mClose,1,0,0,nil); /* enable "Close" menu item */
- SetMenuItem(mOpen,-1,0,0,nil); /* disable "Open" menu item */
- }
-
- void DeactivateDoc(short n)
- {
- #pragma unused (n)
- SetMenuItem(mClose,-1,0,0,nil); /* disable "Close" menu item */
- SetMenuItem(mOpen,1,0,0,nil); /* enable "Open" menu item */
- }
-
- void LetsQuit(short n,short menuItem,short menuRef)
- {
- #pragma unused (n,menuItem,menuRef)
- gQuitApp++;
- }
-
- #define kWindowWidth 200
- #define kWindowHeight 100
-
- void OpenWindow(short n,short menuItem,short menuRef)
- {
- #pragma unused (n,menuItem,menuRef)
- Rect r;
-
- SetRect(&r,0,0,kWindowWidth,kWindowHeight);
- OffsetRect(&r,20,40);
-
- g.w = InstallWindow(1,"\p",&r,0,wCopyDraw,
- SDrawDoc,SClickDoc,SKeyDoc,nil,
- ActivateDoc,DeactivateDoc,SIdleDoc);
- }
-
- static void SDrawDoc(short n)
- {
- EraseRect(&gBigRect);
- MoveTo(10,50);
- DrawString("\pExamples of QuickTime Music Architecture");
- MoveTo(10,65);
- DrawString("\pDavid Van Brink, 1995");
- MoveTo(10,80);
- DrawString("\p©Apple Computer");
- }
-
- static void SClickDoc(short n,Point p,short mods)
- {
- }
-
- static void SKeyDoc(short n,short key,short code,short mods)
- {
- }
-
- static void SIdleDoc(short n, Boolean front)
- {
- }
-
-
-
-
-
- void InitVars()
- /*
- * Called once at startup: yes, it
- * inits the vars.
- */
- {
- EnterMovies();
- }
-
-
-
- void Bootstrap()
- {
- InitVars();
-
- /*** File Menu ***/
- InstallMenu("\pFile",nil,0);
- InstallMenuItem("\pQuit/Q",LetsQuit,0);
- InstallMenuItem("\p(-",nil,0);
- InstallMenuItem("\pPlay Some Notes/1",PlaySomeNotes,0);
- InstallMenuItem("\pPlay Shepard Melody/¡",PlayShepardMelody,0);
- InstallMenuItem("\pPick Then Play Some Notes/2",PickThenPlaySomeNotes,0);
- InstallMenuItem("\pPlay Some Bent Notes/3",PlaySomeBentNotes,0);
- InstallMenuItem("\pBuild And Play Sequence/4",BuildSequenceAndPlay,0);
- InstallMenuItem("\pBuild Music Movie/5",BuildMusicMovie,0);
- InstallMenuItem("\pUse MIDI Input/6",UseMIDIInput,0);
- /*** Edit Menu ***/
- InstallEditMenu(nil,nil,nil,nil,nil);
-
- OpenWindow(0,0,0);
- }
-
- void Hatstrap()
- /*
- * clean up
- */
- {
- ExitMovies();
- }
-
-